package com.jyxd.web.service.assessment.basic;

import com.jyxd.web.dao.basic.NursingRecordDao;
import com.jyxd.web.data.basic.NursingRecord;
import com.jyxd.web.data.basic.VitalSign;
import com.jyxd.web.data.dto.HttpResult;
import com.jyxd.web.data.dto.SyncNursingRecordDTO;
import com.jyxd.web.util.HttpCode;
import com.jyxd.web.util.UUIDUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.util.*;

import static com.jyxd.web.util.DateUtil.yyyyMMddHHmmssSdfToString;
import static com.jyxd.web.util.ExecuteUtil.errorIfEmpty;

@Service
@Transactional
public class NursingRecordService {

    @Autowired
    private NursingRecordDao nursingRecordDao;

    @Autowired
    private VitalSignService vitalSignService;

    public boolean insert(NursingRecord nursingRecord) {
        return nursingRecordDao.insert(nursingRecord);
    }

    public boolean update(NursingRecord nursingRecord) {
        return nursingRecordDao.update(nursingRecord);
    }

    public NursingRecord queryData(String id) {
        return nursingRecordDao.queryData(id);
    }

    public List<NursingRecord> queryList(Map<String, Object> map) {
        return nursingRecordDao.queryList(map);
    }

    public int queryNum(Map<String, Object> map) {
        return nursingRecordDao.queryNum(map);
    }

    /**
     * 快捷录入--护理单--查询在科病人的护理信息
     *
     * @param map
     * @return
     */
    public List<Map<String, Object>> getListByTime(Map<String, Object> map) {
        return nursingRecordDao.getListByTime(map);
    }

    /**
     * 根据时间和code查询护理对象
     *
     * @param map
     * @return
     */
    public NursingRecord queryDataByTimeAndCode(Map<String, Object> map) {
        return nursingRecordDao.queryDataByTimeAndCode(map);
    }

    /**
     * 护理文书--护理单--护理记录--查询护理记录列表
     *
     * @param map code=score
     * @return
     */
    public List<Map<String, Object>> getListByCode(Map<String, Object> map) {
        return nursingRecordDao.getListByCode(map);
    }

    public List<Map<String, Object>> getListByStartTime(Map<String, Object> map) {
        return nursingRecordDao.getListByStartTime(map);
    }

    /**
     * 同步体温单list数据到生命体征
     *
     * @param syncNursingRecordDTOList
     * @return
     */
    public HttpResult syncNursingRecordVitalSignList(List<SyncNursingRecordDTO> syncNursingRecordDTOList) {
        StringBuffer stringBuffer = new StringBuffer();
        errorIfEmpty(syncNursingRecordDTOList, "同步数据不能为空");
        syncNursingRecordDTOList.forEach(syncNursingRecordDTO -> {
            syncNursingRecordVitalSign(syncNursingRecordDTO, stringBuffer);
        });
        if (!StringUtils.contains(stringBuffer.toString(), "数据同步成功")) {
            stringBuffer.append("数据已存在生命体征中，同步失败");
        }
        return new HttpResult(HttpCode.FAILURE_CODE.getCode(), stringBuffer.toString());
    }

    /**
     * 同步护理单数据到生命体征表
     *
     * @return
     */
    private StringBuffer syncNursingRecordVitalSign(SyncNursingRecordDTO syncNursingRecordDTO, StringBuffer stringBuffer) {
        errorIfEmpty(syncNursingRecordDTO, "护理单同步数据不能为空");
        errorIfEmpty(syncNursingRecordDTO.getPatientId(), "患者id不能为空");
        errorIfEmpty(syncNursingRecordDTO.getVisitCode(), "患者住院号不能为空");
        errorIfEmpty(syncNursingRecordDTO.getDataTime(), "记录时间不能为空");
        errorIfEmpty(syncNursingRecordDTO.getOperatorCode(), "操作人员code不能为空");
        Map map = new HashMap();
        map.put("dataTime", yyyyMMddHHmmssSdfToString(syncNursingRecordDTO.getDataTime()));
        map.put("patientId", syncNursingRecordDTO.getPatientId());
        List<VitalSign> vitalSignList = vitalSignService.queryListByTime(map);
        if (CollectionUtils.isEmpty(vitalSignList)) {
            for (Field field : syncNursingRecordDTO.getClass().getDeclaredFields()) {
                field.setAccessible(true);
                switch (field.getName()) {
                    case "tiwen":
                        saveVitalSign("temperature", syncNursingRecordDTO);
                        break;
                    case "maibo":
                        saveVitalSign("pulse", syncNursingRecordDTO);
                        break;
                    case "xinlv":
                        saveVitalSign("hr", syncNursingRecordDTO);
                        break;
                    case "huxi":
                        saveVitalSign("br", syncNursingRecordDTO);
                        break;
                    case "youchuangxueya":
                        saveVitalSign("ibp", syncNursingRecordDTO);
                        break;
                    case "cvpCm":
                        saveVitalSign("cvp", syncNursingRecordDTO);
                        break;
                    case "cvpMm":
                        saveVitalSign("cvpmmHg", syncNursingRecordDTO);
                        break;
                    case "wuchuangxueya":
                        saveVitalSign("bp", syncNursingRecordDTO);
                        break;
                    default:
                        break;
                }
            }
        } else {
            //TODO 此方法有Bug,需要重新理逻辑
            boolean coerceCoverage = isCoerceCoverage(syncNursingRecordDTO);
            vitalSignList.forEach(vitalSign -> {
                if (!coerceCoverage) {
                    stringBuffer.append(vitalSign.getVisitCode());
                } else {
                    switch (vitalSign.getCode()) {
                        case "temperature": //如果为体温数据且为强制覆盖
                            vitalSign.setContent(syncNursingRecordDTO.getTiwen());
                            vitalSign.setOperatorCode(syncNursingRecordDTO.getOperatorCode());
                            vitalSignService.update(vitalSign);
                            break;
                        case "pulse": //如果为脉搏数据且为强制覆盖
                            vitalSign.setContent(syncNursingRecordDTO.getMaibo());
                            vitalSign.setOperatorCode(syncNursingRecordDTO.getOperatorCode());
                            vitalSignService.update(vitalSign);
                            break;
                        case "hr":
                            vitalSign.setContent(syncNursingRecordDTO.getXinlv());
                            vitalSign.setOperatorCode(syncNursingRecordDTO.getOperatorCode());
                            vitalSignService.update(vitalSign);
                            break;
                        case "br":
                            vitalSign.setContent(syncNursingRecordDTO.getHuxi());
                            vitalSign.setOperatorCode(syncNursingRecordDTO.getOperatorCode());
                            vitalSignService.update(vitalSign);
                            break;
                        case "ibp":
                            vitalSign.setContent(syncNursingRecordDTO.getYouchuangxueya());
                            vitalSign.setOperatorCode(syncNursingRecordDTO.getOperatorCode());
                            vitalSignService.update(vitalSign);
                            break;
                        case "cvp":
                            vitalSign.setContent(syncNursingRecordDTO.getCvpCm());
                            vitalSign.setOperatorCode(syncNursingRecordDTO.getOperatorCode());
                            vitalSignService.update(vitalSign);
                            break;
                        case "cvpmmHg":
                            vitalSign.setContent(syncNursingRecordDTO.getCvpMm());
                            vitalSign.setOperatorCode(syncNursingRecordDTO.getOperatorCode());
                            vitalSignService.update(vitalSign);
                            break;
                        case "bp":
                            vitalSign.setContent(syncNursingRecordDTO.getWuchuangxueya());
                            vitalSign.setOperatorCode(syncNursingRecordDTO.getOperatorCode());
                            vitalSignService.update(vitalSign);
                            break;
                        default:
                            break;
                    }
                }
            });
            stringBuffer.append(vitalSignList.get(0).getVisitCode() + "|");
        }
        return stringBuffer;
    }

    /**
     * 新增新生命体征到数据库
     *
     * @param code
     * @param syncNursingRecordDTO
     */
    private void saveVitalSign(String code, SyncNursingRecordDTO syncNursingRecordDTO) {
        VitalSign vitalSign = new VitalSign();
        vitalSign.setId(UUIDUtil.getUUID());
        vitalSign.setCreateTime(new Date());
        vitalSign.setCreateTime(new Date());
        vitalSign.setUpdateTime(new Date());
        vitalSign.setCode(code);
        vitalSign.setContent(getContent(code, syncNursingRecordDTO));
        vitalSign.setDataTime(syncNursingRecordDTO.getDataTime());
        vitalSign.setPatientId(syncNursingRecordDTO.getPatientId());
        vitalSign.setVisitCode(syncNursingRecordDTO.getVisitCode());
        vitalSign.setVisitId(syncNursingRecordDTO.getVisitCode());
        vitalSign.setOperatorCode(syncNursingRecordDTO.getOperatorCode());
        vitalSign.setStatus(1);
        vitalSignService.insert(vitalSign);
    }


    private String getContent(String code, SyncNursingRecordDTO syncNursingRecordDTO) {
        switch (code) {
            case "temperature": //如果为体温数据且为强制覆盖
                return syncNursingRecordDTO.getTiwen();
            case "pulse": //如果为脉搏数据且为强制覆盖
                return syncNursingRecordDTO.getMaibo();
            case "hr":
                return syncNursingRecordDTO.getXinlv();
            case "br":
                return syncNursingRecordDTO.getHuxi();
            case "ibp":
                return syncNursingRecordDTO.getYouchuangxueya();
            case "cvp":
                return syncNursingRecordDTO.getCvpCm();
            case "cvpmmHg":
                return syncNursingRecordDTO.getCvpMm();
            case "bp":
                return syncNursingRecordDTO.getWuchuangxueya();
            default:
                return "";
        }
    }

    /**
     * 判断是否需要强制覆盖
     *
     * @return
     */
    private boolean isCoerceCoverage(SyncNursingRecordDTO syncNursingRecordDTO) {
        if (Objects.isNull(syncNursingRecordDTO)) {
            return false;
        }
        if (Objects.isNull(syncNursingRecordDTO.getCoerceCoverage())) {
            return false;
        }
        return syncNursingRecordDTO.getCoerceCoverage();
    }
}
